﻿using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace UnityExtensions
{
	public class UObjectPool<T> : IPool<T>, IPoolAsync<T> where T : UnityEngine.Object
	{
		private readonly Queue<T> mList = new Queue<T>();                      //

		protected Func<T> bCreateNew;
		public Action<Action<T>> CreateNewAsync;
		protected Action<T> mResetAction;
		protected Action<T> mGetAction;
		public UObjectPool(Func<T> createNew, Action<T> resetFunc) : this()
		{
			bCreateNew = createNew;
			mResetAction = resetFunc;
		}
		public UObjectPool(Action<Action<T>> createNew, Action<T> resetFunc) : this()
		{
			CreateNewAsync = createNew;
			mResetAction = resetFunc;
		}
		public UObjectPool()
		{
		}
		public void SetGetAction(Action<T> v)
		{
			mGetAction = v;
		}

		/// <summary>
		/// 设置创建函数
		/// </summary>
		/// <param name="v"></param>
		public void SetCreateNew(Func<T> v)
		{
			bCreateNew = v;
		}

		public void SetCreateNewAsync(Action<Action<T>> v)
		{
			CreateNewAsync = v;
		}

		public void SetResetAction(Action<T> v)
		{
			mResetAction = v;
		}
		public T Get()
		{
			var it = mList.Count > 0 ? mList.Dequeue() : bCreateNew();
			excuteGetAction(it);
			return it;
		}

		public void excuteGetAction(T it)
		{
			if (mGetAction != null) mGetAction(it);
		}

		public void Recycle(T item)
		{
			if (mList.Contains(item))
			{
				return;
			}
			if (mResetAction != null) mResetAction(item);
			mList.Enqueue(item);
		}

		public virtual void Clear(Action<T> callAction)
		{
			while (mList.Count > 0)
			{
				var it = mList.Dequeue();
				callAction(it);
			}
		}

		public void Get(Action<T> call)
		{
			if (mList.Count > 0)
			{
				var it = mList.Dequeue();
				excuteGetAction(it);
				call(it);
			}
			else
			{
				if (CreateNewAsync == null)
				{
					throw new ArgumentNullException("CreateNewAsync");
					//return;
				}
				CreateNewAsync(it =>
				{
					excuteGetAction(it);
					call(it);
				});
			}
		}
	}
}
